﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace br.ita.CTC34.GLCToAPConverter
{
    public class Converter
    {
        public static Automata GLCtoAP(GLC glc)
        {
            if (glc == null)
            {
                return null;
            }

            Automata ap = new Automata();

            ap.initialState = "q0";

            ap.finalStates = new ArrayList();
            ap.finalStates.Add("qf");

            ap.intermediateStates = new ArrayList();
            ap.intermediateStates.Add("q");

            ap.emptyStackSymbol = "$";
            ap.emptyStringSymbol = glc.emptyStringSymbol;

            ap.tapeSymbols = new ArrayList();
            ap.stackSymbols = new ArrayList();

            ap.tapeSymbols.Add(glc.emptyStringSymbol);
            ap.stackSymbols.Add("$");
            ap.stackSymbols.Add(glc.emptyStringSymbol);

            foreach (string c in glc.endSymbols)
            {
                ap.tapeSymbols.Add(c);
                ap.stackSymbols.Add(c);
            }

            foreach (string c in glc.nonEndSymbols)
            {
                ap.stackSymbols.Add(c);
            }

            ap.transitions = new ArrayList();

            // (q0,e, e) -> (q, S$)
            APTransition startTransition = new APTransition(
                ap.initialState, ap.emptyStringSymbol, ap.emptyStringSymbol,
                (string)ap.intermediateStates[0], glc.initialSymbol.ToString() + ap.emptyStackSymbol.ToString());

            ap.transitions.Add(startTransition);

            APTransition terminalSymbolTransition;
            foreach (string c in glc.endSymbols)
            {
                // (q, a, a) -> (q, e)
                terminalSymbolTransition = new APTransition(
                    (string)ap.intermediateStates[0], c, c,
                    (string)ap.intermediateStates[0], ap.emptyStringSymbol.ToString());

                ap.transitions.Add(terminalSymbolTransition);
            }

            APTransition complexProductionTransitions;
            foreach (DictionaryEntry p in glc.productions)
            {
                foreach (String s in (ArrayList)p.Value)
                {
                    //(q, e, A) -> (q, P)
                    complexProductionTransitions = new APTransition(
                        (string)ap.intermediateStates[0], ap.emptyStringSymbol, p.Key.ToString(),
                        (string)ap.intermediateStates[0], s);

                    ap.transitions.Add(complexProductionTransitions);
                }
            }

            //(q, e, $) -> (qf, e)
            APTransition finalTransition = new APTransition(
                (string)ap.intermediateStates[0], ap.emptyStringSymbol, ap.emptyStackSymbol,
                (string)ap.finalStates[0], ap.emptyStringSymbol.ToString());

            ap.transitions.Add(finalTransition);

            return ap;
        }
    }
}
